#!/bin/bash

# 检测是否存在指定进程
## 参数1是要检测的文件名，参数2是无结果需要执行的命令，参数3是有结果需要执行的命令
grepProc() {
	# 检测是否存在指定进程，返回检测到名字的进程数量
	procNum=$(ps -ef | grep -iw "$1" | wc -l)
	# 确保 procNum 是数字
	case "$procNum" in
	''|*[!0-9]*) procNum=0 ;;
	esac

	# 如果没有检测到进程，则执行参数2的命令
	if [ "$procNum" -le 1 ]; then
		$2
	# 如果检测到相关进程，则执行参数3的命令
	elif [ "$procNum" -gt 1 ]; then
		$3
	fi
}

# 获取可执行文件的路径
queryExecUri() {
	read -r -- binName _ <<< "$1"
	local program_path=$(command -v "$binName")

	if [ -z "$program_path" ]; then
		echo "未找到程序: $binName" >&2
		return 1
	else
		echo "$program_path"
		return 0
	fi
}

# 使用程序a执行程序b
runWith() {
	# 接收任意数量参数，表示要执行的程序及参数
	if [ $# -eq 0 ]; then
		echo "Usage: runWith command [args...]" >&2
		return 1
	fi

	local binB=$1
	local pathSetsid=$(queryExecUri "setsid")

	if [ -z "$pathSetsid" ]; then
		echo "Error: Failed to find executable: setsid" >&2
		return 1
	fi
	
	# 排除系统环境变量可能带来的问题，通过程序路径来执行
	local binB_path=$(queryExecUri "$binB")
	if [ -z "$binB_path" ]; then
		echo "Error: Failed to find executable: $binB" >&2
		return 1
	fi

	# 使用 setsid 启动程序b
	local tmp_log
	tmp_log=$(mktemp 2>/dev/null)
	if [ -z "$tmp_log" ]; then
		echo "Error: Failed to create temporary log file" >&2
		return 1
	fi

	trap 'rm -f "${tmp_log}"' RETURN INT TERM

	local allArgs="$*"
	read -r -- binB args <<< "$allArgs"
	echo "$pathSetsid" "$@"
	nohup "$pathSetsid" "$binB_path" $args >"$tmp_log" 2>&1 &
	local pid=$!

	if ps -p "$pid" >/dev/null 2>&1; then
		echo "Started background process with PID: $pid"
		return 0
	else
		echo "Error: Failed to start program in background: $binB_path $args" >&2
		cat "$tmp_log" >&2
		return 1
	fi
}

# 模拟点击指定坐标
simulateClickAtPosition() {
	local screen="$1"
	local clickX="$2"
	local clickY="$3"

	xdotool mousemove --screen "$screen" "$clickX" "$clickY" click 1
}

# 查找窗口ID
findWindowIdentifier() {
	local mode="$1" # title: 标题匹配, class: 程序名（WM_CLASS）匹配
	local identifier="$2"

	if [ "$mode" = "title" ]; then
		# 通过窗口标题查找可见窗口
		wmctrl -l | grep -i "$identifier" | awk '{print $1}'
	elif [ "$mode" = "class" ]; then
		# 通过 WM_CLASS（程序名）查找窗口
		wmctrl -lx | grep -i "$identifier" | awk '{print $1}'
	else
		echo "错误：无效的查找模式 '$mode'，支持 'title' 或 'class'" >&2
		return 1
	fi
}

# 执行窗口操作
performWindowAction() {
	local action="$1" # focus, min, max, close
	local windowId="$2"

	if [ -z "$windowId" ]; then
		echo "错误：未提供有效的窗口 ID。"
		return 1
	fi

	case "$action" in
	focus)
		wmctrl -i -a "$windowId"
		;;
	min)
		wmctrl -i -b add,hidden -t 0 -r "$windowId"
		;;
	max)
		wmctrl -i -b add,maximized_vert,maximized_horz -t 0 -r "$windowId"
		;;
	close)
		wmctrl -i -c "$windowId"
		;;
	*)
		echo "未知操作: $action" >&2
		return 1
		;;
	esac
}

setWindowPosition() {
	local action="$1" # move, resize
	local windowId="$2"
	local param1="$3" # x / width
	local param2="$4" # y / height

	if [ -z "$windowId" ]; then
		echo "错误：未提供有效的窗口 ID。"
		return 1
	fi

	case "$action" in
	move)
		# 移动窗口到指定坐标 (x, y)
		if [ -z "$param1" ] || [ -z "$param2" ]; then
			echo "错误：移动操作需要 X 和 Y 坐标参数。"
			return 1
		fi
		xdotool windowmove "$windowId" "$param1" "$param2"
		;;
	resize)
		# 设置窗口大小为指定宽度和高度
		if [ -z "$param1" ] || [ -z "$param2" ]; then
			echo "错误：调整大小操作需要宽度和高度参数。"
			return 1
		fi
		xdotool windowsize "$windowId" "$param1" "$param2"
		;;
	*)
		echo "未知操作: $action" >&2
		return 1
		;;
	esac
}

monitorAndActOnWindow() {
    local match_type="$1"
    local target="$2"
    local timeout="$3"
    local action="$4"
    shift 4

    local interval=1
    local elapsed=0
    local windowId

    while [ "$elapsed" -lt "$timeout" ]; do
        windowId=$(findWindowIdentifier "$match_type" "$target")

        if [ -n "$windowId" ]; then
            if type "$action" | grep -q 'function'; then
                "$action" "$@" "$windowId"
            else
                eval "$action"
            fi
            return 0
        fi

        sleep "$interval"
        elapsed=$((elapsed + interval))
    done

    echo "超时：未找到符合条件的窗口 ($match_type: $target)"
    return 1
}
